/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mygame.Input;

import java.nio.FloatBuffer;

import com.jme3.collision.CollisionResult;
import com.jme3.collision.CollisionResults;
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseAxisTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.math.Ray;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.VertexBuffer.Type;
import com.jme3.system.JmeContext;
import mygame.Manager;
import mygame.Backbone.GlobalVars;
import mygame.Collision.FindCollidingVertex;
import mygame.Object.GameObject;

/**
 *
 * @author Tobi
 */
public class InputHandler implements AnalogListener, ActionListener {

    private InputManager ipm;
    private TerraformHandler terra;

    public InputHandler(InputManager inputManager) {
        this.ipm = inputManager;
        this.terra = new TerraformHandler();
    }

    public void onAnalog(String name, float value, float tpf) {
    	if(name.equals(GlobalVars.ACTION_MOUSE_MOVE)){
        	if(terra.getState()>0){
	        	//Ray ray = new Ray(Manager.GetInstance().getMyCam().getCamera().getLocation(), Manager.GetInstance().getMyCam().getCamera().getDirection());
        		Ray ray = getMouseClick3DRay();
        		CollisionResults res = new CollisionResults();
        		Manager.GetInstance().getPlanetManager().getUniverse().collideWith(ray, res);
	
	            CollisionResult r = res.getClosestCollision();
	            
	            if (r != null) {
	            	terra.move(r.getContactPoint());
	            }
        	}
        }
    	
    }

    private Ray getMouseClick3DRay(){
    	Vector2f click2d = ipm.getCursorPosition();
    	Camera cam = Manager.GetInstance().getMyCam().getCamera();
        Vector3f click3d = cam.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f).clone();
        Vector3f dir = cam.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 1f).subtractLocal(click3d).normalizeLocal();
        return new Ray(click3d, dir);
    }
    
    public void onAction(String name, boolean isPressed, float tpf) {
        if (name.equals(GlobalVars.ACTION_ESC) && !isPressed) {
            //context.destroy(false);
            Manager.GetInstance().StopGame();
        }
        else if (name.equals(GlobalVars.ACTION_LEFT_CLICK) && isPressed) {
            
        	//Ray ray = new Ray(Manager.GetInstance().getMyCam().getCamera().getLocation(), Manager.GetInstance().getMyCam().getCamera().getDirection());
            Ray ray = getMouseClick3DRay();
        	CollisionResults res = new CollisionResults();
            Manager.GetInstance().getPlanetManager().getUniverse().collideWith(ray, res);

            CollisionResult r = res.getClosestCollision();
            
            if (r != null) {
                //Find node With UserData
                Geometry s = r.getGeometry();
                terra.start(s);
                //FindCollidingVertex.incrVol(s, r.getContactPoint(), 0.2f);
//                while (!s.getName().contains("Models/")) {
//                    s = s.getParent();
//                }
//                int id = (Integer) s.getUserData("GameObject_id");
//                GameObject go = Manager.GetInstance().getModelManager().InteractiveObjects.get(id);
//                go.interact();
            }
        }
        else if (name.equals(GlobalVars.ACTION_LEFT_CLICK) && !isPressed) {
        	terra.stop();
        }else if (name.equals(GlobalVars.ACTION_MENU) && !isPressed) {
            //context.destroy(false);
            Manager.GetInstance().setupMenuKeys();
            Manager.GetInstance().getGUIManager().callMenu();
            //this.ipm.clearMappings();
        }else if(name.equals(GlobalVars.ACTION_ALT) && isPressed){
        	terra.setSubtract();
        }
        else if(name.equals(GlobalVars.ACTION_ALT) && !isPressed){
        	terra.setAdd();
        }
    }

    public void setupGameKeys() {
		ipm.addMapping(GlobalVars.ACTION_ESC, new KeyTrigger(KeyInput.KEY_ESCAPE));
		ipm.addMapping(GlobalVars.ACTION_MENU, new KeyTrigger(KeyInput.KEY_M));
		ipm.addMapping(GlobalVars.ACTION_LEFT_CLICK, new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
		ipm.addMapping(GlobalVars.ACTION_ALT, new KeyTrigger(KeyInput.KEY_LMENU));
		//mouse movement
		ipm.addMapping(GlobalVars.ACTION_MOUSE_MOVE, new MouseAxisTrigger(MouseInput.AXIS_Y,true));
		ipm.addMapping(GlobalVars.ACTION_MOUSE_MOVE, new MouseAxisTrigger(MouseInput.AXIS_Y,false));
		ipm.addMapping(GlobalVars.ACTION_MOUSE_MOVE, new MouseAxisTrigger(MouseInput.AXIS_X,false));
		ipm.addMapping(GlobalVars.ACTION_MOUSE_MOVE, new MouseAxisTrigger(MouseInput.AXIS_X,true));
        
        String[] mapping = new String[]{
            GlobalVars.ACTION_ESC,
            GlobalVars.ACTION_LEFT_CLICK,
            GlobalVars.ACTION_MENU,
            GlobalVars.ACTION_MOUSE_MOVE,
            GlobalVars.ACTION_ALT
        };

        //add listener        
        ipm.addListener(this, mapping);
    }

    public void clearMappings() {
        ipm.clearMappings();
    }
    
    public InputManager getInputManager(){
    	return this.ipm;
    }
}
